package cn.aitrox.ry.app.web.service.impl;

import cn.aitrox.ry.app.web.service.ComponentService;
import cn.aitrox.ry.bean.CommonPageInfo;
import cn.aitrox.ry.common.service.BaseService;
import cn.aitrox.ry.constant.CommonConstant;
import cn.aitrox.ry.service.config.bean.ComponentDataDefine;
import cn.aitrox.ry.service.config.dto.ComponentDto;
import cn.aitrox.ry.service.config.dto.in.ComponentSearchInDto;
import cn.aitrox.ry.service.config.enumtype.ComponentTypeEnum;
import cn.aitrox.ry.service.config.feign.ComponentFeign;
import cn.aitrox.ry.util.ArrayUtil;
import cn.aitrox.ry.util.JSONUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ComponentServiceImpl extends BaseService implements ComponentService {

    public final static String CONCAT_SYMBOL = "@#@";
    public final static String POINT_SYMBOL = "->";
    public final static String MINUS_NUM_1 = "-1";
    public final static String NOTHING = "无";

    @Autowired
    @Lazy
    private ComponentFeign componentFeign;

    public Map<Integer, ComponentDto> getAllCompoentMap() {
        ComponentSearchInDto in = new ComponentSearchInDto();
        in.setPage(1);
        in.setPageSize(100000);
        CommonPageInfo<ComponentDto> searchResult = componentFeign.search(in);
        if (ArrayUtil.isEmpty(searchResult.getList())) {
            return new HashMap<>();
        }

        return searchResult.getList().stream().collect(Collectors.toMap(ComponentDto::getId, x -> x));
    }

    public String getComponentText(String compType, Map<String, String> comDataParseMap, String value) {
        if (ArrayUtil.isEmpty(comDataParseMap)) {
            return CommonConstant.EMPTY;
        }
        if (ComponentTypeEnum.TEXT.getType().equalsIgnoreCase(compType)) {
            return value;
        }
        String[] valueSplitArr = value.split(CommonConstant.DEFAULT_SEPARATOR);
        List<String> valList = new ArrayList<>();
        for (String valuesSplit : valueSplitArr) {
            String text = comDataParseMap.get(valuesSplit);
            if (null == text) {
                String tmpText;
                try {
                    String val = Double.valueOf(valuesSplit).longValue() + CommonConstant.EMPTY;
                    tmpText = comDataParseMap.get(val) == null ? CommonConstant.EMPTY : comDataParseMap.get(val);
                } catch (NumberFormatException e) {
                    tmpText = valuesSplit;
                }
                valList.add(tmpText);
            } else {
                valList.add(text);
            }
        }
        return StringUtils.join(valList, CommonConstant.DEFAULT_SEPARATOR);
    }

    public Map<String, String> parseData2ValNameMap(ComponentDto component) {
        Map<String, String> map = null;
        String type = component.getType();
        String data = component.getData();

        ComponentTypeEnum enumType = ComponentTypeEnum.getEnumByType(type);
        if (null == enumType) {
            return map;
        }
        switch (enumType) {
            case SELECT:
                map = this.parseDataBySelect(data);
                break;
            case CHILD_SELECT:
                map = this.parseDataByChildSelect(data);
                break;
            case CHECKBOX:
                map = this.parseDataByCheckbox(data);
                break;
            case RADIOBOX:
                map = this.parseDataByRadiobox(data);
                break;
            case TEXT:
                map = new HashMap<>();
                break;
            default:
                map = new HashMap<>();
                break;
        }
        return map;
    }

    // [{"text":"阴性","code":"1"},{"text":"阳性","code":"2"}]
    private Map<String, String> parseDataBySelect(String data) {
        Map<String, String> map = null;

        try {
            List<ComponentDataDefine> componentData1PoList = JSONUtil.parseArray(data, ComponentDataDefine.class);
            map = new HashMap<>();
            for (ComponentDataDefine componentData1Po : componentData1PoList) {
                map.put(componentData1Po.getCode(), componentData1Po.getText());
            }
        } catch (Exception e) {
        }
        if (null == map) {
            List<ComponentDataDefine> componentData2PoList = JSONUtil.parseArray(data, ComponentDataDefine.class);
            map = new HashMap<>();
            for (ComponentDataDefine componentData2Po : componentData2PoList) {
                map.put(componentData2Po.getCode() + CommonConstant.EMPTY, componentData2Po.getText());
            }
        }
        String defaultCode = MINUS_NUM_1;
        String defaultText = NOTHING;
        if (null == map.get(defaultCode)) {
            map.put(defaultCode, defaultText);
        }
        return map;
    }

    // [{"text":"阴性","code":"1","child:[{"text":"阳性","code":"2"}]"},{"text":"阳性","code":"2"}]
    private Map<String, String> parseDataByChildSelect(String data) {
        Map<String, String> map = new HashMap<>();

        List<ComponentDataDefine> componentData1PoList = JSONUtil.parseArray(data, ComponentDataDefine.class);

        this.parseComponentDataItem(map, componentData1PoList, null);

        String defaultCode = MINUS_NUM_1;
        String defaultText = NOTHING;
        if (null == map.get(defaultCode)) {
            map.put(defaultCode, defaultText);
        }
        return map;
    }

    private void parseComponentDataItem(Map<String, String> codeTextMap, List<ComponentDataDefine> componentData1PoList, String parentItemCode) {
        for (ComponentDataDefine componentData1Po : componentData1PoList) {
            String currentItemCode;
            if (null == parentItemCode) {
                currentItemCode = componentData1Po.getCode();
                codeTextMap.put(currentItemCode, componentData1Po.getText());
            } else {
                String parentItemText = codeTextMap.get(parentItemCode);
                currentItemCode = parentItemCode + CONCAT_SYMBOL + componentData1Po.getCode();
                String currentItemText = parentItemText + POINT_SYMBOL + componentData1Po.getText();
                codeTextMap.put(currentItemCode, currentItemText);
            }
            if (!ArrayUtil.isEmpty(componentData1Po.getChild())) {
                this.parseComponentDataItem(codeTextMap, componentData1Po.getChild(), currentItemCode);
            }
        }
    }

    private Map<String, String> parseDataByRadiobox(String data) {
        return this.parseDataBySelect(data);
    }

    private Map<String, String> parseDataByCheckbox(String data) {
        return this.parseDataBySelect(data);
    }

}
